/*
    SUSAN® - Sole of Unix Save ANything

   

   

   

   
*/
#include <algorithm>
#include <vector>

#if defined(HAVE_MINGW)
#include "include/susan.h"
#include "gtest/gtest.h"
#else
#include "gtest/gtest.h"
#include "include/susan.h"
#endif


#include "lib/version.h"

TEST(version_strings, version)
{
  std::string ver_full{kSusanVersionStrings.Full};

  // the full version is not a nullstring
  EXPECT_GT(strlen(kSusanVersionStrings.Full), 0);

  // the full version contains at least two dots (.)
  EXPECT_GE(std::count(ver_full.begin(), ver_full.end(), '.'), 2);

  // the version starts with a digit
  EXPECT_TRUE(isdigit(kSusanVersionStrings.Full[0]));

  // version + date is set correctly
  std::string full_with_date{kSusanVersionStrings.FullWithDate};
  std::string ref_full_with_date =
      ver_full + " (" + kSusanVersionStrings.Date + ")";
  EXPECT_EQ(full_with_date, ref_full_with_date);
}

TEST(version_strings, dates)
{
  const size_t date_len{strlen(kSusanVersionStrings.Date)};
  const std::string date{kSusanVersionStrings.Date};
  const std::string short_date{kSusanVersionStrings.ShortDate};

  // shortest possible is a date in May like "01 May 2019"
  EXPECT_GT(date_len, 10);

  // check format of date
  EXPECT_TRUE(isdigit(kSusanVersionStrings.Date[0]));
  EXPECT_TRUE(isdigit(kSusanVersionStrings.Date[1]));
  EXPECT_EQ(kSusanVersionStrings.Date[2], ' ');
  EXPECT_EQ(kSusanVersionStrings.Date[date_len - 5], ' ');
  EXPECT_TRUE(isdigit(kSusanVersionStrings.Date[date_len - 4]));
  EXPECT_TRUE(isdigit(kSusanVersionStrings.Date[date_len - 3]));
  EXPECT_TRUE(isdigit(kSusanVersionStrings.Date[date_len - 2]));
  EXPECT_TRUE(isdigit(kSusanVersionStrings.Date[date_len - 1]));

  const int day = std::stoi(date.substr(0, 2));
  EXPECT_GT(day, 0);
  EXPECT_LT(day, 32);

  // check that our month is a real month
  const std::vector<std::string> months{
      "January", "February", "March",     "April",   "May",      "June",
      "July",    "August",   "September", "October", "November", "December"};

  EXPECT_NE(std::find(std::begin(months), std::end(months),
                      date.substr(3, date_len - 8)),
            std::end(months));

  // year should have a sane value
  const int year = std::stoi(date.substr(date_len - 4, 4));
  EXPECT_GT(year, 2018);
  EXPECT_LT(year, 2100);

  // year is exactly 4 chars long
  EXPECT_EQ(strlen(kSusanVersionStrings.Year), 4);
  // all these chars are digits
  EXPECT_TRUE(isdigit(kSusanVersionStrings.Year[0]));
  EXPECT_TRUE(isdigit(kSusanVersionStrings.Year[1]));
  EXPECT_TRUE(isdigit(kSusanVersionStrings.Year[2]));
  EXPECT_TRUE(isdigit(kSusanVersionStrings.Year[3]));

  // year should be consistent across variables
  EXPECT_EQ(year, atoi(kSusanVersionStrings.Year));
  EXPECT_EQ(year % 1000, atoi(kSusanVersionStrings.ShortDate + 5));
  EXPECT_EQ(year, atoi(kSusanVersionStrings.ProgDateTime));

  // construct shortdate from date and check if it matches
  std::string ref_short_date =
      date.substr(0, 2) + date.substr(3, 3) + date.substr(date_len - 2, 2);
  EXPECT_EQ(short_date, ref_short_date);
}

TEST(version_strings, messages)
{
  // just make sure these strings contain at least some text
  EXPECT_GT(strlen(kSusanVersionStrings.BinaryInfo), 10);
  EXPECT_GT(strlen(kSusanVersionStrings.ServicesMessage), 10);
  EXPECT_GT(strlen(kSusanVersionStrings.JoblogMessage), 10);
}
